package net.nohaven.proj.javeau.fs.crypt;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import net.nohaven.proj.javeau.fs.FSUtils;
import net.nohaven.proj.javeau.fs.exceptions.ConditionsNotMetException;
import net.nohaven.proj.javeau.fs.exceptions.EntityNotFoundException;
import net.nohaven.proj.javeau.fs.model.FSDirectory;
import net.nohaven.proj.javeau.fs.model.FSFile;
import net.nohaven.proj.javeau.fs.model.FSItem;
import net.nohaven.proj.javeau.utils.Utils;

public class CFSUtils {
	private static final String[] HEX = new String[] { "0", "1", "2", "3", "4",
			"5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F" };

	private static final Set<String> BASE_DIR_CONTENT = new HashSet<String>();
	static {
		BASE_DIR_CONTENT.add(CFSFilesystem.TOC_FILE);
		BASE_DIR_CONTENT.add("..");
		for (String hex : HEX)
			BASE_DIR_CONTENT.add(hex);
	}

	public static String iv2path(byte[] iv) {
		StringBuffer realPath = new StringBuffer(Utils.bytes2Hex(iv));
		realPath.insert(2, '/');
		realPath.insert(1, '/');
		return realPath.toString();
	}

	public static boolean isSecretDirectory(FSDirectory fsDir) {
		FSItem index = fsDir.get(CFSFilesystem.TOC_FILE);

		if (index == null || !FSUtils.isFile(index))
			return false;

		FSFile idx = (FSFile) index;
		try {
			InputStream is = idx.getContent();
			byte[] magic = new byte[CFSFilesystem.MAGIC.length];
			is.read(magic);
			is.close();
			return Arrays.equals(magic, CFSFilesystem.MAGIC);
		} catch (EntityNotFoundException e) {
			return false;
		} catch (IOException e) {
			return false;
		}
	}

	public static boolean isSecretDirectory(File dir) {
		File index = new File(dir, CFSFilesystem.TOC_FILE);

		if (!index.exists() || !index.isFile())
			return false;

		try {
			InputStream is = new FileInputStream(index);
			byte[] magic = new byte[CFSFilesystem.MAGIC.length];
			is.read(magic);
			is.close();
			return Arrays.equals(magic, CFSFilesystem.MAGIC);
		} catch (IOException e) {
			return false;
		}
	}

	public static void createDirs(File dir) throws ConditionsNotMetException {
		if (dir.list().length > 0 && dir.list().length != 17)
			throw new ConditionsNotMetException("Directory is not empty");

		for (byte i = 0; i < 16; i++) {
			File l1 = new File(dir, HEX[i]);
			for (byte j = 0; j < 16; j++) {
				File l2 = new File(l1, HEX[j]);
				l2.mkdirs();
			}
		}
	}
}
